<!--
 * @Author: '浪川' '1214391613@qq.com'
 * @Date: 2025-07-05 16:20:35
 * @LastEditors: '浪川' '1214391613@qq.com'
 * @LastEditTime: 2025-07-07 15:06:57
 * @FilePath: \passiflora-edulis-sims\src\components\ScrambleDisplayComponent.vue
 * @Description: 字母拼写单词的 展示
 *
 * Copyright (c) 2025 by '1214391613@qq.com', All Rights Reserved.
-->

<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import { App, Frame } from 'leafer-ui'
import type { ITextAlign } from 'leafer-ui'
import { BoxText } from 'src/components/MyLeaferCutom'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)
import '@leafer-in/export' // 引入导出元素插件 //
import '@leafer-in/view' // 引入导出元素插件 //

import { useQuasar } from 'quasar'
import { useScrambleStore } from 'src/stores/scramble-store'

const puzzle_store = useScrambleStore()
const $q = useQuasar()

const answer = ref<string[]>([])
const max_wordlen = ref<number>(0) // 最长的单词长度

const req_scramble = () => {
  $q.notify({ type: 'positive', message: '生成成功', position: 'top' })

  answer.value = puzzle_store.words
  max_wordlen.value = puzzle_store.max_wordlen
  generate_puzzle(answer.value, max_wordlen.value)
}
/**
 * @description: 绘制拼图
 * @param {*} answers: 输入答案
 * @return {*}:
 */
const generate_puzzle = (answers: string[], max_wordlen: number) => {
  // 清除画布的元素
  answer_frame.clear()
  topic_frame.clear()

  const x_len = max_wordlen
  const y_len = answers.length + 1

  // 让 两个画布自适应
  topic_frame.width = x_len * 2 * 500 + 100 * 2
  topic_frame.height = y_len * 500 + 100 * 2 * answers.length

  answer_frame.width = x_len * 2 * 500 + 100 * 2
  answer_frame.height = y_len * 500 + 100 * 2 + 200 * answers.length

  answer_frame.x = topic_frame.width + 200
  // 遍历 answer
  let row_num = 0
  for (const row of answers) {
    let col_num = 0

    // 打乱单词
    const shuffle_word = shuffle(row.split(''))

    // 先放置 shuffle_word
    // 获取实际渲染位置
    const real_x =
      puzzle_store.box_width * col_num +
      100 -
      puzzle_store.stroke_width * col_num

    const real_y =
      puzzle_store.box_width * row_num +
      100 -
      puzzle_store.stroke_width * row_num +
      200 * row_num

    const words_box_len = (puzzle_store.box_width * max_wordlen) / 2

    topic_frame.add(
      create_boxtext(
        shuffle_word.join(''),
        real_x,
        real_y,
        'left',
        words_box_len,
        '#ffffff'
      )
    )
    answer_frame.add(
      create_boxtext(
        shuffle_word.join(''),
        real_x,
        real_y,
        'left',
        words_box_len,
        '#ffffff'
      )
    )

    for (const ans_w of row) {
      // 创建 答案box
      // 获取实际渲染位置
      if (ans_w == ' ') {
        col_num++
        continue
      }
      /**
       * 公式为：box 的宽度 * 当前的列 + 100的两边留白 + box 的描边宽度 * 当前列 + 前一个Box的位置 + 500的间隔
       */
      const real_x =
        puzzle_store.box_width * col_num +
        100 -
        puzzle_store.stroke_width * col_num +
        words_box_len +
        500

      const real_y =
        puzzle_store.box_width * row_num +
        100 -
        puzzle_store.stroke_width * row_num +
        200 * row_num
      topic_frame.add(create_boxtext('', real_x, real_y))
      answer_frame.add(create_boxtext(ans_w, real_x, real_y))
      col_num++
    }
    row_num++
  }
  leafer_app.value.tree.zoom('fit', 0)
}

const shuffle = (array: string[]) => {
  return array.sort(() => Math.random() - 0.5)
}

/**
 * @description:
 * @param {*} text: 展示的文字、
 * @param {string} text_align: 文件的水平排版方式
 * @param {*} x: x轴坐标
 * @param {*} y: y 轴坐标
 * @param {number|undefined} width: 方框宽度
 * * @param {number|undefined} stroke_color: 方框颜色
 * @return {*}: BoxText组件样式
 */
const create_boxtext = (
  text: string,

  x: number,
  y: number,
  text_align: ITextAlign = 'center',
  width: number | undefined = undefined,
  stroke_color: string | undefined = undefined
) => {
  if (stroke_color == undefined) {
    stroke_color = puzzle_store.box_color
  }
  if (width == undefined) {
    width = puzzle_store.box_width
  }
  const font_size = puzzle_store.box_width * 0.8
  const box = new BoxText({
    text: text,
    text_color: puzzle_store.text_color,
    text_align: text_align,
    font_size: font_size,
    width: width,
    height: puzzle_store.box_width,
    x: x,
    y: y,
    editable: true,
    stroke: {
      type: 'solid',
      color: stroke_color,
      style: { strokeWidth: puzzle_store.stroke_width },
    },
    hitChildren: false, // 阻止直接选择子元素（防止父子选择冲突，可双击进入组内选择子元素）
  })
  return box
}

/**
 * @description: 重新渲染
 */
const reset_puzzle = () => {
  generate_puzzle(answer.value, max_wordlen.value)
}

/**
 * @description: 导出图层
 */
const answer_topic_export = async () => {
  await answer_frame.export('answer.png')
  await topic_frame.export('topic.png')
}
const leafer_app = ref<App>(new App()) // 存储 Leafer 实例

// 创建一个 题目画布
const topic_frame = new Frame({
  width: puzzle_store.puzzle_size[0],
  height: puzzle_store.puzzle_size[1],
  x: 0,
  y: 0,
})
// 创建 答案画布
const answer_frame = new Frame({
  width: puzzle_store.puzzle_size[0],
  height: puzzle_store.puzzle_size[1],
  x: puzzle_store.puzzle_size[0] + 200,
  y: 0,
})
onMounted(() => {
  leafer_app.value = new App({
    view: 'leafer-view',
    editor: {},
    fill: '#ecfcff',
  })
  // 将画布添加进 app
  leafer_app.value.tree.add(answer_frame)
  leafer_app.value.tree.add(topic_frame)

  const answer_box = new BoxText({
    text: 'Answer',
    text_color: puzzle_store.text_color,
    font_size: 500 * 0.8,
    width: 1500,
    height: 500,
    x: 100,
    y: 100,
    editable: true,
    stroke: {
      type: 'solid',
      color: '#32cd79',
      style: { strokeWidth: puzzle_store.stroke_width },
    },
    hitChildren: false, // 阻止直接选择子元素（防止父子选择冲突，可双击进入组内选择子元素）
  })
  answer_frame.add(answer_box)
  const topic_box = new BoxText({
    text: 'Topic',
    text_color: puzzle_store.text_color,
    font_size: 500 * 0.8,
    width: 1500,
    height: 500,
    x: 100,
    y: 100,
    editable: true,
    stroke: {
      type: 'solid',
      color: '#32cd79',
      style: { strokeWidth: puzzle_store.stroke_width },
    },
    hitChildren: false, // 阻止直接选择子元素（防止父子选择冲突，可双击进入组内选择子元素）
  })
  topic_frame.add(topic_box)
  setTimeout(() => {
    leafer_app.value.tree.zoom('fit', 0)
  }, 1000)
})
</script>
<template>
  <div class="row q-gutter-sm">
    <div class="col-1">
      <q-btn
        style="width: 100%"
        color="primary"
        label="生成"
        @click="req_scramble"
      />
    </div>

    <div class="col-1">
      <q-btn
        style="width: 100%"
        color="primary"
        label="重置"
        @click="reset_puzzle"
      />
    </div>
    <div class="col-1">
      <q-btn
        style="width: 100%"
        color="primary"
        label="导出"
        @click="answer_topic_export"
      />
    </div>
  </div>
  <div style="margin-top: 1%; padding: 1px; background-color: #ecfcff">
    <div id="leafer-view"></div>
  </div>
</template>
<style lang="sass" scoped>
#leafer-view
  position: absolute;
  height:67vh
  left:0;
</style>
